/**
 * @file mid_Timer.c
 * @author Linquan  
 * @brief  虚拟定时器，提供四个定时器，时间间隔最小1ms。
 *          提供 使能定时器以及关闭定时器的函数
 * @version 1.0
 * @date 2024-06-14
 * 
 * @copyright Copyright (c) 2024
 * 
 */


#include "mid_Timer.h"
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>

#include "macro_overload.h"


#define TICK_1MS            1000
#define TIMER_TICK        TICK_1MS

#define MS_ADD(X)         (X/1000)  


/* 模拟定时器列表 */
Mid_Timer_t Timer_arry[E_TIMER_MAX] ;

/* 定时器线程启动标志位 */
static uint8_t Timer_thrad_used = 0;

/* 根据秒计算微妙 */
const unsigned long Converter = 1000 * 1000; // 1s == 1000 * 1000 us

/* 定时器线程 */
pthread_t Mid_Timer_Thread;

/* 互斥锁 */
pthread_mutex_t Mid_Timer_mutes = PTHREAD_MUTEX_INITIALIZER;

/**
 * @brief 模拟定时器的线程
 * 
 * @param arg 
 * @return void* 
 */
void * Hardware_Timer_handle(void *arg)
{
    struct timeval current_timer,last_time;
    uint64_t diff_time = 0;

    /* 获取上次时间 */
    gettimeofday(&last_time, NULL);
   
    while (1)
    {   
        /* 1、 获取当前时间 */
        gettimeofday(&current_timer, NULL);

        /* 2、计算 时间差 */
        diff_time = (current_timer.tv_sec * Converter + current_timer.tv_usec)\
                    - (last_time.tv_sec * Converter + last_time.tv_usec);

        /* 3、当大于1ms，就执行一次 */
        if(diff_time >= TIMER_TICK)
        {
            last_time = current_timer;

            pthread_mutex_lock(&Mid_Timer_mutes);

            for(int i = 0; i < E_TIMER_MAX; i++)
            {
                /* 3.1、当该定时器被使用 */
                if(Timer_arry[i].enable)
                {
                    /* 3.2、定时器计数累加 */
                    Timer_arry[i].count += MS_ADD(TIMER_TICK);
                
                     /* 3.3、计数累加超时，执行回调函数 */
                    if(Timer_arry[i].count >= Timer_arry[i].ticks)
                    {
                        Timer_arry[i].count  = 0;

                        if(Timer_arry[i].Timer_callbak != NULL)
                        {
                            Timer_arry[i].Timer_callbak();
                        }
                    }
                }       
            }
            pthread_mutex_unlock(&Mid_Timer_mutes);
        }
    }    
}


/**
 * @brief 设置选择定时器并配置参数
 * 
 * @param timer_n : E_TIMER_1 ~ E_TIMER_4
 * @param timer 
 */
uint8_t Mid_Timer_Set(Timer_number_t timer_n,\
                    uint32_t ticks,
                    Mid_Timer_callback Timer_callbak)
{
    if(timer_n >= E_TIMER_MAX)
    {
        return 1;
    }
    else if(Timer_callbak == NULL)
    {
        return 2;
    }

    if(Timer_thrad_used == 0)
    {
        Timer_thrad_used ++;
        /* TODO：创建定时器线程 */
        pthread_create(&Mid_Timer_Thread, NULL, Hardware_Timer_handle, NULL);
    }

    Timer_arry[timer_n].ticks = ticks;
    Timer_arry[timer_n].Timer_callbak = Timer_callbak;
    Timer_arry[timer_n].enable = 1;

    return 0;
}

/**
 * @brief 关闭定时器
 * 
 * @param timer_n 
 */
uint8_t Mid_Timer_Reset(Timer_number_t timer_n)
{
    if(timer_n >= E_TIMER_MAX)
    {
        return 1;
    }

    uint8_t timer_enable_num = 0;
    Timer_arry[timer_n].enable = 0;

    /* TODO：“遍历四个定时器对象的状态，如果都未使能，则删除线程 */
    foreach(Mid_Timer_t, Timer_arry, item )
    {
        timer_enable_num += item->enable;
    }
    if(timer_enable_num == 0)
    {
        Timer_thrad_used = 0;
         pthread_exit(&Mid_Timer_Thread);
    }
    return 0;
}








